package code

import common.EnginService
import common.Message
import common.ServerAttributeKey
import io.netty.channel.Channel
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.handler.timeout.IdleState
import io.netty.handler.timeout.IdleStateEvent
import org.slf4j.LoggerFactory

/**
 * 服务器网络层业务接受handler
 * 由此像业务层派发业务
 * @author King
 */
class ClientChannelHandler : SimpleChannelInboundHandler<Message>() {

    private lateinit var service: EnginService

    fun setEnginService(service: EnginService) {
        this.service = service
    }

    @Throws(Exception::class)
    override fun channelActive(ctx: ChannelHandlerContext) {
        super.channelActive(ctx)
        service.channelManager.addChannel(ctx.channel())
    }

    @Throws(Exception::class)
    override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
        super.exceptionCaught(ctx, cause)
        ctx.close()
    }

    @Throws(Exception::class)
    override fun channelRead0(ctx: ChannelHandlerContext, msg: Message) {
        val handler = service.handlerManager.getHandler(msg.getmId(), msg.gethId())
        service.messageDispatch.put(handler,msg)
    }

    @Throws(Exception::class)
    override fun userEventTriggered(ctx: ChannelHandlerContext, evt: Any) {
        if (evt !is IdleStateEvent) {
            return
        }
        val channel = ctx.channel()
        //1次写超时就发送心跳包
        if (evt.state() == IdleState.WRITER_IDLE) {
            //发送心跳包
            val msg = Message.newMessage()
            msg.setmId(Message.M_ID)
            msg.sethId(Message.H_SEND_HEART_BEAT)
            channel.writeAndFlush(msg)
        }
        //2次读超时就认为断开连接了
        if (evt.state() == IdleState.READER_IDLE) {
            val attr = channel.attr(ServerAttributeKey.netChannel)
            val netChannel = attr.get()
            if (netChannel != null) {
                if (!netChannel.isHeartBeat) {
                    netChannel.isHeartBeat = true
                    return
                }
            }
            ctx.close()
            //        	断开连接
            //        	disconnet(channel);
            println("not recieve heart beat")
        }
    }


    @Throws(Exception::class)
    override fun channelInactive(ctx: ChannelHandlerContext) {
        super.channelInactive(ctx)
        disconnet(ctx.channel())
    }

    @Throws(Exception::class)
    private fun disconnet(channel: Channel) {
        service.channelManager.delChannel(channel)
        val attr = channel.attr(ServerAttributeKey.netChannel)
        val netChannel = attr.get()
        if (netChannel == null || netChannel.isKick) {
            return
        }
        //抛出掉线消息给业务线程
        val msg = Message.newMessage()
        msg.channel = attr.get()
        msg.setmId(Message.M_ID)
        msg.sethId(Message.H_DISCONNET)
        val handler = service.handlerManager.getHandler(msg.getmId(), msg.gethId())
        service.messageDispatch.put(handler,msg)
    }

    companion object {


        private val log = LoggerFactory.getLogger(ClientChannelHandler::class.java)
    }
}
